package com.ygqh.baby.controller.admin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.foxinmy.weixin4j.type.TradeType;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.Constant;
import com.ygqh.baby.controller.utils.DocumentHandler;
import com.ygqh.baby.model.YgOrder4ImportModel;
import com.ygqh.baby.model.YgSkuTemplate;
import com.ygqh.baby.po.YgLogistics;
import com.ygqh.baby.po.YgOrder;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.wechat.YgWeChatService;
import com.ygqh.baby.service.wechat.message.YgTemplateMessage;
import com.ygqh.baby.service.wechat.protocol.UnifiedOrderReqData;
import com.ygqh.baby.utils.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Controller
@RequestMapping("/admin/order")
public class OrderController extends BaseController<Object, java.lang.Long> {

	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private FileService fileService;
	@Autowired
	private YgLogisticsService ygLogisticsService;
	@Autowired
	private YgSkuService skuService;
	@Autowired
	private WxSmallMessageService wxSmallMessageService;
	@Autowired
	private YgOrderPaymentService orderPaymentService;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgWeChatService weChatService;
	@Autowired
	private YgOrderLogService ygOrderLogService;
	@Autowired
	private WxMpMessageService wxMpMessageService;

	@Value("${micro.msg.appId}")
	private String appid;
	@Value("${wechat.pay.mchid}")
	private String mchid;
	@Value("${micro.msg.secret}")
	private String appsecret;
	@Value("${wechat.pay.notify_url}")
	private String notify_url;
	@Value("${wechat.pay.key}")
	private String key;
	@Value("${trustoner.supplier.id}")
	private Long TRUSTONE_SUPPLIER_ID;

	@RequestMapping("searchOrder")
	@ResponseBody
	public Map<String, Object> searchOrder(String q, QueryInfo queryInfo, Date startDate, Date endDate, OrderStatus orderStatus, Long orderId, String telPhone,
			String productName) {

		ResultSet<YgOrder> resultSet = ygOrderService.search(queryInfo, null, orderId, null, orderStatus, startDate, endDate, q, getSession().getUserName(),
				telPhone, null, null, null, OrderType.Ordinary, productName);

		return resultSet.toDatatables(null);
	}

	@RequestMapping("orderDetail")
	@ResponseBody
	public YgOrder orderDetail(Long orderId) {

		return ygOrderService.findOrderDetail(orderId);
	}

	@RequestMapping("sendOrder")
	@ResponseBody
	public Message sendOrder(Long orderId, String expressCompany, String expressCode, String logisticsCode) {
		YgLogistics ygLogistics = new YgLogistics();
		ygLogistics.setOrderId(orderId.toString());
		ygLogistics.setSendTime(new Date());
		ygLogistics.setCreateTime(ygLogistics.getSendTime());
		ygLogistics.setExpressCode(expressCode);
		ygLogistics.setExpressCompany(expressCompany);
		ygLogistics.setLogisticsCode(logisticsCode);
		ygLogisticsService.save(ygLogistics);

		YgOrder ygOrder = new YgOrder();
		ygOrder.setOrderId(orderId);
		ygOrder.setSendTime(ygLogistics.getSendTime());
		ygOrder.setOrderStatus(OrderStatus.WaitingSign);
		ygOrderService.updateByOrderId(ygOrder);

		sendMsgForPlatform(orderId.toString(), ygLogistics);
		return SUCCESS_MESSAGE;
	}

	@RequestMapping("payOrder")
	@ResponseBody
	public Message payOrder(Long orderId, BigDecimal totalPrice, PayType payType, HttpServletRequest request, HttpServletResponse response) {
		ygOrderService.splitOrderV2(orderId, totalPrice, PayType.WeChat);
		return SUCCESS_MESSAGE;
	}

	@RequestMapping("downloadOrderTemplate")
	public void downloadOrderTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
		byte[] bytes = fileService.downloadFromOss("template/yiigoo_order_template.xlsx");
		DocumentHandler.createDownload(bytes, "壹果订单模板.xlsx", request, response);
	}

	@RequestMapping("downloadSkuTemplate")
	public void downloadSkuTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException {
		byte[] bytes = fileService.downloadFromOss("template/yiigoo_sku_template.xlsx");
		List<YgSkuTemplate> skuTemplates = skuService.findSkuTemplate();
		skuTemplates.forEach(t -> {
			if (t.getWholesalePrice().doubleValue() == 0) {
				t.setWholesalePrice(t.getSalesPrice());
			}
		});
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put("resultSet", skuTemplates);
		DocumentHandler.DownloadExcel(bytes, "壹果商品SKU编码文档.xlsx", dataMap, request, response);
	}

	@RequestMapping("loadOrderExcel")
	@ResponseBody
	public Message loadOrderExcel(@RequestParam("uploadFile") MultipartFile uploadFile, HttpServletRequest request, HttpServletResponse respons)
			throws IOException {

		InputStream is = uploadFile.getInputStream();
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);

		Map map = new HashMap();
		List<YgOrder4ImportModel> orderList = new ArrayList<>();
		try {
			// Read the Sheet
			for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
				XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
				if (xssfSheet == null) {
					continue;
				}
				// Read the Row
				for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
					XSSFRow xssfRow = xssfSheet.getRow(rowNum);
					if (xssfRow != null) {
						XSSFCell skuCode = xssfRow.getCell(0);
						XSSFCell quantity = xssfRow.getCell(1);
						XSSFCell receiver = xssfRow.getCell(2);
						XSSFCell telPhone = xssfRow.getCell(3);
						XSSFCell provinceName = xssfRow.getCell(4);
						XSSFCell cityName = xssfRow.getCell(5);
						XSSFCell areaName = xssfRow.getCell(6);
						XSSFCell address = xssfRow.getCell(7);
						YgOrder4ImportModel model = new YgOrder4ImportModel();
						model.setSkuCode(getValue(skuCode));
						model.setQuantity(Long.valueOf(getValue(quantity)));
						model.setReceiver(getValue(receiver));
						model.setTelPhone(getValue(telPhone));
						model.setProvinceName(getValue(provinceName));
						model.setCityName(getValue(cityName));
						model.setAreaName(getValue(areaName));
						model.setAddress(getValue(address));
						checkData(model);
						YgOrder4ImportModel dbModel = skuService.findOrder4ImportModel(model.getSkuCode());
						if (dbModel == null) {
							String r = model.getRemark();
							model.setRemark(r + "SKU不存在;");
						} else {
							model.setProductName(dbModel.getProductName());
							model.setSizeName(dbModel.getSizeName());
							if (dbModel.getWholesalePrice().doubleValue() == 0) {
								model.setSalesPrice(dbModel.getSalesPrice());
							} else {
								model.setSalesPrice(dbModel.getWholesalePrice());
							}
						}
						orderList.add(model);

					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return Message.error(orderList);
		}

		return Message.success(orderList);
	}

	private void checkData(YgOrder4ImportModel model) {
		StringBuilder remark = new StringBuilder();
		if (model.getSkuCode() == null) {
			remark.append("请填写有效的SKU;");
		}
		if (model.getQuantity() == null || model.getQuantity().intValue() <= 0) {
			remark.append("请填写有效的购买数量;");
		}
		if (model.getReceiver() == null) {
			remark.append("请填写有效的收货人姓名;");
		}
		if (model.getTelPhone() == null || model.getTelPhone().length() != 11) {
			remark.append("请填写有效的收货人手机号;");
		}
		if (model.getProvinceName() == null || model.getCityName() == null || model.getAreaName() == null) {
			remark.append("请填写有效的省市区;");
		}
		if (model.getAddress() == null) {
			remark.append("请填写有效的收货地址;");
		}

		model.setRemark(remark.toString());
	}

	/**
	 * 得到Excel表中的值
	 *
	 * @param hssfCell
	 *            Excel中的每一个格子
	 * @return Excel中每一个格子中的值
	 */
	@SuppressWarnings("static-access")
	private String getValue(XSSFCell hssfCell) {
		if (hssfCell == null)
			return null;
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			// 返回布尔类型的值
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			DecimalFormat df = new DecimalFormat("0");
			String str = df.format(hssfCell.getNumericCellValue());
			// 返回数值类型的值
			return str;
		} else {
			// 返回字符串类型的值
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}

	@RequestMapping("saveImportOrder")
	@ResponseBody
	Message saveImportOrder(String orderList) {
		List<YgOrder4ImportModel> order4ImportModels = JSON.parseObject(orderList, new TypeReference<List<YgOrder4ImportModel>>() {
		});
		return ygOrderService.saveImportOrder(order4ImportModels, getSession().getId());
	}

	@RequestMapping("delOrder")
	@ResponseBody
	Message delOrder(Long orderId) {
		ygOrderService.deleteSoft(orderId, getSession().getId());
		return SUCCESS_MESSAGE;
	}

	@RequestMapping("qrPayOrder")
	@ResponseBody
	public Message qrPayOrder(String state, HttpServletRequest request, HttpServletResponse response) {

		JSONPObject json = null;
		Message msg = null;
		String ipAddress = WebUtils.getIpAddr(request);
		System.out.println("客户端ip：" + ipAddress);
		String[] split = ipAddress.split(",");
		ipAddress = split[0];
		System.out.println("客户端ip：" + ipAddress);
		System.out.println("微信支付回调地址：" + notify_url);
		String[] str = state.split("-");
		String coderUrl = "";
		// 判断该订单是否已经支付过
		YgOrder ygOrder = ygOrderService.findByOrderId(Long.parseLong(str[0]));
		if (ygOrder != null && !ygOrder.getOrderStatus().equals(OrderStatus.WaitingPay)) {
			return SUCCESS_MESSAGE;
		}
		try {
			// 生成支付流水
			Long paymentCode = ygFrameCodeService.getFrameCode(CodeType.OrderPM, new Date());
			orderPaymentService.addPaymentRecord(str[0], new BigDecimal(str[1]), paymentCode.toString(), PayType.WeChat, AppType.WeChat);

			UnifiedOrderReqData reqData = new UnifiedOrderReqData.UnifiedOrderReqDataBuilder(appid, mchid, "壹果订单", paymentCode.toString(),
					new BigDecimal(str[1]).multiply(new BigDecimal(100)).intValue(), ipAddress, notify_url, TradeType.NATIVE.name()).setProduct_id("000")
							.build();
			msg = weChatService.UnifiedOrderNATIVE(reqData);
			coderUrl = (String) msg.getExtra();
			coderUrl = this.getPayCode(coderUrl, paymentCode, request);

		} catch (Exception e) {
			ygOrderLogService.addOrderLog(Long.parseLong(str[0]), OrderStatus.WaitingPay, getSession().getUserName(), "发起微信支付失败" + e.getMessage());
			e.printStackTrace();
			return ERROR_MESSAGE;
		}

		return new Message(Message.Type.success, coderUrl);
	}

	private String getPayCode(String coderUrl, Long paymentCode, HttpServletRequest request) {
		String path = request.getRealPath("/");
		String realPath = path + "/PayCodeImage";
		String fileName = "payCode" + paymentCode + ".jpg";
		String qrcodeUrl = "";
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			realPath = QRCodeUtil.encode(coderUrl, realPath, fileName);
			if (!StringUtil.isBlank(realPath)) {
				File file = new File(realPath);
				String str = file.toString();

				String ext = fileName.split("\\.")[1];
				String imageTmpUrl = request.getSession().getServletContext().getRealPath("/") + UUID.randomUUID().toString() + "" + "." + ext;
				GenerateImage(str, imageTmpUrl);
				File file1 = new File(imageTmpUrl);
				System.out.println(file1.getAbsolutePath());
				System.out.println(file1.getName());
				qrcodeUrl = fileService.uploadImage(file, new FileType[] { FileType.PayCode }, ext, true, request);

			}
		} catch (Exception e) {

			e.printStackTrace();
		}
		return qrcodeUrl;

	}

	public static boolean GenerateImage(String imgStr, String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片
		if (imgStr == null || null == imgFilePath) // 图像数据为空
			return false;
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			// Base64解码
			byte[] b = decoder.decodeBuffer(imgStr);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}
			// 生成jpeg图片
			OutputStream out = new FileOutputStream(imgFilePath);
			out.write(b, 0, b.length);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	@RequestMapping("downloadSendOrderTemplate")
	public void downloadSendOrderTemplate(HttpServletRequest request, HttpServletResponse response) {
		byte[] bytes = fileService.downloadFromOss("template/yiigoo_send_order_template.xlsx");
		DocumentHandler.createDownload(bytes, "壹果订单发货模板.xlsx", request, response);
	}

	@RequestMapping("loadSendOrderExcel")
	@ResponseBody
	public Message loadSendOrderExcel(@RequestParam("uploadFile") MultipartFile uploadFile, HttpServletRequest request, HttpServletResponse respons)
			throws IOException {

		InputStream is = uploadFile.getInputStream();
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
		Map map = new HashMap();
		List<YgLogistics> orderList = new ArrayList<>();

		List<String> noSendList = ygOrderService.getNoSendOrderListBySupplier(getSupplier().getId());

		try {
			// Read the Sheet
			for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
				XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
				if (xssfSheet == null) {
					continue;
				}
				// Read the Row
				for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
					XSSFRow xssfRow = xssfSheet.getRow(rowNum);
					if (xssfRow != null) {
						XSSFCell orderId = xssfRow.getCell(0);
						XSSFCell productName = xssfRow.getCell(1);
						XSSFCell skuCode = xssfRow.getCell(2);
						XSSFCell expressCompany = xssfRow.getCell(3);
						XSSFCell expressCode = xssfRow.getCell(4);
						YgLogistics model = new YgLogistics();
						model.setProvinceName(getValue(productName));
						model.setAddress(getValue(skuCode));
						model.setOrderId(getValue(orderId));
						model.setExpressCompany(getValue(expressCompany));
						model.setExpressCode(getValue(expressCode));
						checkSendData(model, noSendList);
						orderList.add(model);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return Message.error(orderList);
		}

		return Message.success(orderList);
	}

	private YgLogistics checkSendData(YgLogistics model, List<String> orderList) {
		StringBuilder remark = new StringBuilder();
		if (model.getOrderId() == null) {
			remark.append("订单编号不能为空;");
		}
		if (model.getProvinceName() == null) {
			remark.append("商品名称不能为空;");
		}
		if (model.getAddress() == null) {
			remark.append("SKU编码不能为空;");
		}
		if (model.getExpressCompany() == null) {
			remark.append("请填写物流公司;");
		}
		if (model.getExpressCode() == null) {
			remark.append("请填写物流单号;");
		}
		if (orderList.indexOf(model.getOrderId()) == -1) {
			remark.append("订单编号不存在或已发货;");
		}
		model.setAreaName(remark.toString());
		return model;

	}

	@RequestMapping("updateSendOrder")
	@ResponseBody
	public Message updateSendOrder(String orderList) {
		List<YgLogistics> ygLogistics = JSON.parseObject(orderList, new TypeReference<List<YgLogistics>>() {
		});
		if (ygLogistics.get(0).getAddress() == null && ygLogistics.get(0).getProvinceName() == null) {
			return Message.error("提交数据有误,请刷新页面试试");
		}
		// 先判断导入的数据是否有发生退款的
		List<Long> list = new ArrayList<Long>();
		List<String> returnList = new ArrayList<String>();
		Long supplierId = getSupplier().getId();
		for (YgLogistics log : ygLogistics) {

			int i = ygOrderService.selectReturnByOrder(supplierId, Long.valueOf(log.getOrderId()), log.getAddress());
			if (i > 0)
				returnList.add(log.getOrderId());
		}
		if (returnList != null && returnList.size() > 0) {
			return Message.error(returnList);
		}

		ygOrderService.updateLogistics(ygLogistics);
		SendTemplate(ygLogistics);

		return Message.success(null);

	}

	// 发模板消息
	private void SendTemplate(List<YgLogistics> ygLogs) {
		ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				List<Map<String, Object>> list = ygOrderService.selectOpenIdByOrder(ygLogs);
				// 循环List
				for (Map<String, Object> map : list) {
					String orderId = map.get("orderId").toString();
					Optional<YgLogistics> stream = ygLogs.stream().filter(m -> orderId.equals(m.getOrderId().toString())).findFirst();
					if (stream.isPresent()) {
						YgLogistics log = stream.get();

						if (map.get("platformNo") == null || Constant.YIIGOO_PLATFORM_NO.equals(map.get("platformNo"))) {

							String openId = map.get("openId").toString();
							String title = "亲,您购买的壹果商品已经发货啦！收到商品后请给予评价哦！";

							wxMpMessageService.sendOrderSendMsg(title, orderId, log.getExpressCompany(), log.getExpressCode(), log.getProvinceName(), openId);

						} else {
							sendMsgForPlatform(orderId, log);
						}
					}

				}
			}
		});
	}

	private void sendMsgForPlatform(String orderId, YgLogistics log) {
		try {
			if (!YgStringUtils.isNum(orderId)) {
				return;
			}
			YgOrder order = ygOrderService.findOrderDetailByOrderId(Long.valueOf(orderId));
			YgTemplateMessage tplMsg = wxSmallMessageService.
					getOrderSendMsgByPlatform(order, log.getExpressCompany(), log.getExpressCode());
			tplMsg.setPlatformNo(order.getPlatformNo());
			wxSmallMessageService.sendTmplMsg(tplMsg);
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("exportOrder")
	public void exportOrder(Long q, Date startDate, Date endDate, String telPhone, OrderStatus orderStatus, HttpServletRequest request,
			HttpServletResponse response) {
		endDate = DateConvertUtils.addDay(endDate, 1);
		Long supplierId = getSupplier().getId();

		List<Map<String, Object>> list = ygOrderService.getOrderDetailBySupplier(q, startDate, endDate, orderStatus, telPhone, supplierId);
		if (supplierId.compareTo(TRUSTONE_SUPPLIER_ID) == 0) {
			list.forEach(map -> {
				map.put("identityNo", IDAuthUtil.decryptIdNo(map.get("identityNo").toString()));
			});
		}
		byte[] bytes = fileService.downloadFromOss("template/supplierorderlist.xlsx");
		List<Map<String, Object>> dataMaps = new ArrayList<Map<String, Object>>();
		Map<String, Object> dataMap = new HashMap<String, Object>();

		dataMap.put("resultSet", list);
		dataMaps.add(dataMap);
		DocumentHandler.DownloadExcel(bytes, "订单明细.xlsx", dataMap, request, response);
	}

	@RequestMapping("searchOrderBySupplier")
	@ResponseBody
	public Map<String, Object> searchOrderBySupplier(String q, QueryInfo queryInfo, Date startDate, Date endDate, String telPhone, OrderStatus orderStatus,
			HttpServletRequest request, HttpServletResponse response) {
		Long supplierId = getSupplier().getId();
		ResultSet<YgOrder> resultSet = ygOrderService.searchBySupplier(queryInfo, q, orderStatus, startDate, endDate, supplierId, telPhone);

		return resultSet.toDatatables(null);
	}

	@RequestMapping("getOrderDetail")
	@ResponseBody
	public Map<String, Object> getOrderDetail(Long q, HttpServletRequest request, HttpServletResponse response) {
		Long supplierId = getSupplier().getId();
		List<Map<String, Object>> list = ygOrderService.getOrderDetailBySupplier(q, null, null, null, null, supplierId);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("order", list);
		List<YgLogistics> logistics = ygLogisticsService.findByOrderId(q, supplierId);
		if (logistics != null && logistics.size() > 0) {
			map.put("logistics", logistics);
		}

		/*
		 * Long supplierId=getSupplierId(); YgOrderInfoModel
		 * order=ygOrderService.selectOrderDetailBySupplierOrderId(q,
		 * supplierId);
		 * 
		 * List<YgLogistics> logistics =
		 * ygLogisticsService.findByOrderId(q.toString()); if (logistics != null
		 * && logistics.size() > 0) { order.setLogisticsList(logistics); }
		 */

		return map;
	}

}
